#include "serialportservice.h"
#include "config/config.h"

#include <BinaryFileUtil.h>
#include <PathUtils.h>
#include <QTimer>


///单导心电实例化串口服务
/// 这里解析心电的数据协议和心率计算
///https://gitee.com/abaiweb/health/blob/master/service/src/script/ecg/h600.lua
SerialPortService::SerialPortService( QObject *parent ):serialPortUtils(new SerialPortUtils(parent)),m_running(false),m_processThread(nullptr)
{
    // 连接信号和槽
    connect(serialPortUtils, &SerialPortUtils::connectionStatusChanged, this, &SerialPortService::updateConnectionStatus);
    //实例，信号回调，槽函数
    connect(serialPortUtils, &SerialPortUtils::dataReceived, this, &SerialPortService::displayReceivedData);
    // //查找文件
    // QString currentWorkDir = Config::currentWorkDir();
    // //向上移动两级目录  这里根据自己情况调整，模拟数据的源数据在 源代码根目录
    // currentWorkDir = PathUtils::moveUpLevels(currentWorkDir, 3);
    // QString ecg_sample_data_path = currentWorkDir + "/ecg_sample_data.bin";
    // qDebug() << "模拟数据文件路径:" << ecg_sample_data_path;
    // fileUtil =  new BinaryFileUtil(ecg_sample_data_path, this);
}
//析构函数
SerialPortService::~SerialPortService()
{
     qDebug() << "~SerialPortService...";
    if(serialPortUtils){
        serialPortUtils->disconnectPort();
        delete serialPortUtils;
        serialPortUtils = nullptr;
    }
}
//接收数据
void SerialPortService::displayReceivedData(const QByteArray &newData)
{
    //打印接收到的数据长度
    //qDebug() << "接收到数据长度:" << newData.size();
    if (!isTest && !serialPortUtils) {
        return;
    }
    if (newData.isEmpty()) {
        return;
    }
    // 将新数据添加到缓冲区
    m_buffer.append(newData);
    // 加锁保护数据队列
    QMutexLocker locker(&m_mutex);

    // 查找完整的数据帧
    int startIndex = 0;
    while (startIndex < m_buffer.size() - 1) {
        // 查找 AA 55 起始标志
        if (static_cast<quint8>(m_buffer[startIndex]) == 0xAA &&
            static_cast<quint8>(m_buffer[startIndex + 1]) == 0x55) {

            // 查找下一个 AA 55 作为结束位置
            int nextStart = -1;
            for (int i = startIndex + 2; i < m_buffer.size() - 1; ++i) {
                if (static_cast<quint8>(m_buffer[i]) == 0xAA &&
                    static_cast<quint8>(m_buffer[i + 1]) == 0x55) {
                    nextStart = i;
                    break;
                }
            }
            if (nextStart != -1) {
                // 找到完整的一帧数据
                QByteArray frame = m_buffer.mid(startIndex, nextStart - startIndex);
                m_datas.enqueue(frame);
                startIndex = nextStart;
            } else {
                // 没有找到下一帧的开始，保留数据等待更多数据
                if (startIndex > 0) {
                    m_buffer = m_buffer.mid(startIndex);
                }
                break;
            }
        } else {
            startIndex++;
        }
        // 如果缓冲区过大，清理无效数据
        if (m_buffer.size() > 1024) {
            // 查找最后一个 AA 55
            int lastStart = -1;
            for (int i = m_buffer.size() - 2; i >= 0; --i) {
                if (static_cast<quint8>(m_buffer[i]) == 0xAA &&
                    static_cast<quint8>(m_buffer[i + 1]) == 0x55) {
                    lastStart = i;
                    break;
                }
            }
            if (lastStart != -1) {
                m_buffer = m_buffer.mid(lastStart);
            } else {
                m_buffer.clear();
            }
        }
    }
}
//状态
void SerialPortService::updateConnectionStatus( const ConnectionStatus status, const QString &message )
{
    //打印状态
    qDebug() << "串口连接状态更新:" << static_cast<int>(status) << ", 信息:" << message;
    if( status == ConnectionStatus::Connected  && m_processThread == nullptr && !m_running  ){
        qDebug() << "串口已连接，准备接收数据...";
        // 创建数据处理线程
        startWork();
    }
    emit connectionStatusChanged(status,message);
}
void SerialPortService::startWork()
{
    m_running = true;
    qDebug() << "工作线程启动:" << QThread::currentThread();
    m_processThread = new QTimer(this);
    connect(m_processThread, &QTimer::timeout, this, &SerialPortService::processData);
    m_processThread->start(50); // 每秒处理一次队列
}
void SerialPortService::stopWork()
{
    m_running = false;
    if (m_processThread) {
        m_processThread->stop();
        m_processThread->deleteLater();
        m_processThread = nullptr;
    }
}
//处理数据
void SerialPortService::processData(){
    if( !m_running ) return;
    //打印m_datas 队列长度
    // QMutexLocker locker(&m_mutex);
    // if (!m_datas.isEmpty()) {
    //     // 取出一条完整数据
    //     QByteArray data = m_datas.dequeue();
    //     locker.unlock();  // 及时释放锁
    //     // 转换为16进制字符串
    //     QString hexString = data.toHex(' ').toUpper();
    //     // 发射数据接收信号
    //     //emit dataReceived(data);

    //     qDebug() <<  "处理数据线程，数据队列长度:" << m_datas.size();
    //     qDebug() <<  "hexString:" << hexString;
    // }
    QByteArray data;
    {
        // 使用作用域限制锁的生命周期
        QMutexLocker locker(&m_mutex);
        if (m_datas.isEmpty()) {
            return;  // 没有数据，继续循环
        }
        data = m_datas.dequeue();
        // locker 在这里离开作用域，自动解锁
    }  // 锁在这里自动释放
    if( data.isEmpty() ) return ;
    // 转换为16进制字符串
    //QString hexString = data.toHex(' ').toUpper();
    // 发射数据接收信号
    //emit dataReceived(data);
    //qDebug() <<  "处理数据线程，数据队列长度:" << m_datas.size();
    //qDebug() <<  "hexString:" << hexString;
    int size = data.size() ;
    if (size< 6) {
        qDebug() << "数据长度不足，忽略";
        return;
    }

    //fileUtil->writeBinary(data); //保存数据到文件  模拟数数据存储
    switch( size ){
        case 6: //设备的测量和停止按钮状态
        if( static_cast<quint8>(data[2]) == 0x30 ){
            if( static_cast<quint8>(data[4]) == 0x01 ){
                qDebug() << "开始测量指令已发送";
                DataPacket packet("开始测量指令");
                emit dataReceived(packet);
                return;
            }
            else if( static_cast<quint8>(data[4]) == 0x02){
                qDebug() << "停止测量指令已发送";
                 DataPacket packet("停止测量指令已发送");
                emit dataReceived(packet);
                return;
            }
        }
        break;
        case 7:
        if( static_cast<quint8>(data[2]) == 0x31 ){

            if( static_cast<quint8>(data[5]) == 0x00 ){
                qDebug() << "设备工作状态: 待机中";
                DataPacket packet("设备工作状态: 待机中");
                emit dataReceived(packet);
                return;
            }else if(static_cast<quint8>(data[4]) == 0x02 && static_cast<quint8>(data[5]) == 0x80 ){
                //80  => 1000 0000
                quint8  value = static_cast<quint8>(data[5]) ;
                int bit7 = (value >> 7) & 0x01;  // 右移7位后取最低位
                int bit6 = (value >> 6 ) & 0x01;  // 右移6位后取最低位
                QString hexString = data.toHex(' ').toUpper();
                qDebug() <<  "hexString:" << hexString;
                QString msg = "";
                if( bit7 == 1 ){
                    qDebug() << "设备工作状态: 1：测量中";
                    msg.append("设备工作状态: 1：测量中;");
                }else if( bit6 == 0 ){
                    qDebug() << "设备工作状态: 0：ecg没连上";
                    msg.append("设备工作状态: 0：ecg没连上;");
                }
                DataPacket packet(msg);
                emit dataReceived(packet);
                return;
            }
        }

        break;
        case 8:
            if( static_cast<quint8>(data[2]) == 0x31 &&
                static_cast<quint8>(data[3]) == 0x04 &&
                static_cast<quint8>(data[4]) == 0x01 &&
                static_cast<quint8>(data[5]) == 0x23 &&
                static_cast<quint8>(data[6]) == 0x22
                ){
                qDebug() << "版本：2.3，硬件版本2.2";
                return;
            }
            break;
        case 9:
            //测量结果
            if( static_cast<quint8>(data[2]) == 0x33 &&
                static_cast<quint8>(data[3]) == 0x05 &&
                static_cast<quint8>(data[4]) == 0x01 ){
                int resIndex = static_cast<quint8>(data[5]);
                //测量结果
                QString msg = QString("测量结果:%1");
                resIndex = resIndex > 0x0F ? 16 : resIndex;// 0xff 表示16
                msg = msg.arg( res[ resIndex ]);
                qDebug() << "测量结果:" << msg;
                //心率值
                int hr = static_cast<quint8>(data[7]);
                qDebug() << "接收到心率值:" << hr;
                DataPacket packet(msg,hr);
                emit dataReceived(packet);
            }
            break;
        default:
            //心电数据
            if( static_cast<quint8>(data[2]) == 0x32  &&
                static_cast<quint8>(data[3]) == 0x37 ){
                quint8  dataType = static_cast<quint8>(data[4]);
                if( dataType == 0x01 ){//表示为波形  8位心电数据包，高位是预留
                    //倒数第二个字节是导联脱落标志
                   quint8 leadStatus =  static_cast<quint8>(data[size-2]) ; //导联脱落标志
                   QString lead = ( leadStatus == 0x00 ) ? "导联连接正常" : "导联连接脱落";
                   //心电数据解析
                   QList<int> ecgValues;
                   QString  jump = "无博动";
                   for( int i = 6 ; i < size - 3 ; i +=2 ){
                       //每两个字节表示一个心电数据点，高位在前，低位在后
                       quint8 highByte = static_cast<quint8>(data[i]);
                       quint8 lowByte = static_cast<quint8>(data[i+1]);
                       //求高位的d7
                       int d7 = (highByte >> 7) & 0x01;
                       if( d7  == 0 ){//8bit模式 波形最大值是 255， 12bit不处理
                            int d6 = (highByte >> 6) & 0x01;
                            int ecgValue = static_cast<int>(lowByte);
                            ecgValues.append(ecgValue);
                            //是否搏动
                            jump = ( d6 == 1 ) ? "有博动" : "无博动";
                       }
                   }
                   DataPacket packet("",jump,lead,ecgValues);
                   emit dataReceived(packet);
                }
            }
            break;
    }
}

